<template>
  <div class="section">
    <div class="label">选项</div>
    <div class="title">连一连</div>
    <div class="options-box">
      <div class="group">
        <div class="item" v-for="(item, index) in option[1]" :key="item.no">
          <div class="left" :class="{ 'is__current': current.status && current.isOption }">
            <el-input placeholder="请输入选项" v-model="option[0][index].content" />
            <div class="anchor" :class="{ 
              'is__checked': (current.status && current.isOption && current.no === item.no) || lines.find(i => i.answer === item.no)
            }" @click="handle(true, item.no)" />
          </div>
          <div class="right" :class="{ 'is__current': current.status && !current.isOption }">
            <el-input placeholder="请输入选项" v-model="option[1][index].content" />
            <div class="anchor" :class="{ 
              'is__checked': (current.status && !current.isOption && current.no === item.no) || item.answer
            }" @click="handle(false, item.no)" />
          </div>
          <i class="el-icon-close" v-if="option.length > 2" @click="remove(index)" />
        </div>
        <div class="match-line" v-for="line in lines" :key="line.no" :style="line.style" />
      </div>
      <el-button icon="el-icon-circle-plus-outline" size="mini" round type="primary" @click="add">添加选项</el-button>
    </div>
  </div>
</template>

<script lang="ts">
import { ref, computed, reactive } from 'vue';
import { ElMessage } from 'element-plus';

export default {
  setup() {
    
    let option = ref([
      Array.from(Array(3), (_, index) => ({ no: index + 1, content: null })),
      Array.from<any, any>(Array(3), (_, index) => ({ no: index + 1, content: null, answer: null }))
    ])
    
    const add = () => {
      let init = { no: option.value[0].length + 1, content: null };
      option.value[0].map((i, idx) => i.no = idx + 1);
      option.value[1].map((i, idx) => i.no = idx + 1);
      option.value[0].push({...init});
      option.value[1].push({ ...init, answer: null });
    }
    const remove = (index) => {
      option.value[0].splice(index, 1);
      option.value[1].splice(index, 1);
      option.value[0].map((i, idx) => i.no = idx + 1);
      option.value[1].map((i, idx) => {i.no = idx + 1; i.answer = null});
    }

    let current = reactive({
      status: false,
      isOption: false,
      no: -1
    });

    const handle = (isOption, no) => {
      if (current.status) {
        if (isOption) {
          option.value[1].map(item => {
            item.answer === no && (item.answer = null);
            item.no === current.no && (item.answer = no);
          });
        } else {
          option.value[1].map(item => {
            item.answer === current.no && (item.answer = null);
            item.no === no && (item.answer = current.no);
          });
        }
      } else {
        current.isOption = isOption;
        current.no = no;
      }
      current.status = !current.status;
    }

    const lines = computed(() => {
      let arr = option.value[1].filter(item => item.answer).map(({no, answer}) => {
        let { sqrt, pow, atan, abs } = Math;
        let height = abs(answer! - no) * (36 + 20);
        let width = sqrt(pow(height, 2) + pow(200, 2) );
        let rotate = 360 * atan( height / 200 )/(2 * Math.PI);
        let style = {
          width: `${ width }px`,
          transform: `rotate(${ answer! < no ? rotate : - rotate }deg)`,
          top: `${ (answer! - 1) * (36 + 20) + 18 }px`,
          left: '220px'
        }
        return { no, answer, style, height }
      });
      return arr;
    })

    const validator = () => {
      if (option.value.flat().some(item => !item.content)) {
        ElMessage.warning('选项不能为空！')
        return false;
      } else if (option.value[1].some(item => !item.answer)) {
        ElMessage.warning('请连接答案');
        return false;
      }
      return {
        option: option.value,
        rightAnswer: option.value[1].map(item => [option.value[0].find(i => i.no === item.answer), item])
      };
    }


    return { option, add, remove, current, handle, lines, validator }
  }
}
</script>

<style lang="scss" scoped>
.options-box {
  overflow: hidden;
  position: relative;
  .match-line {
    width: 0;
    height: 1px;
    background: #72b22a;
    position: fixed;
    box-shadow: 0 0 0 1px #72b22a;
  }
  .group {
    position: relative;
    .match-line {
      height: 1px;
      background: #72b22a;
      position: absolute;
      transform-origin: 0 0;
      pointer-events: none;
    }
    .item {
      margin-bottom: 20px;
      &::after {
        content: '';
        display: block;
        clear: both;
      }
      .left,
      .right {
        float: left;
        width: 220px;
        position: relative;
        &.is__current .anchor {
          pointer-events: none;
        }
        .anchor {
          width: 20px;
          height: 20px;
          border-radius: 50%;
          border: solid 1px #72b22a;
          background: #fff;
          position: absolute;
          top: 50%;
          cursor: pointer;
          &.is__checked,
          &:active {
            z-index: 1;
            &:before {
              display: block;
            }
          }
          &::before {
            content: '';
            display: none;
            width: 60%;
            height: 60%;
            border-radius: 50%;
            background: #72b22a;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate3d(-50%, -50%, 0);
          }
          &:active {
            box-shadow: 0 0 5px #72b22a;
          }
        }
      }
      .left {
        .anchor {
          right: 0;
          transform: translate3d(50%, -50%, 0)
        }
      }
      .right {
        margin-left: 200px;
        .anchor {
          left: 0;
          transform: translate3d(-50%, -50%, 0)
        }
      }
      i.el-icon-close {
        display: block;
        float: right;
        width: 18px;
        height: 18px;
        margin-top: 9px;
        color: #fff;
        line-height: 18px;
        text-align: center;
        background: #a9b3bf;
        border-radius: 2px;
        cursor: pointer;
        &:active {
          transform: scale(0.95);
        }
      }
    }
  }
}
</style>